from boot import (QTableWidget, Union, QWidget, QColor, Qt, QFrame, SmoothScrollDelegate, List, Dict, QTableWidgetItem, SaleInfo, QAbstractItemView,
                  QHBoxLayout, QLabel, TableItemDelegate, LineEditMenu, QStyleOptionViewItem, QModelIndex, QStyledItemDelegate, GlobalWidget, QVBoxLayout,
                  logger, FontFamily)
from .qq9_line_edit import QQ9NoSizeLineEdit, QQ9NoSizeNumberLineEdit
from utils.format import amount_format


TABLE_CONTENT_FONT_COLOR: str = "#909399"


class QQ9TabelWidget(QFrame):

    def __init__(self, parent: Union[QWidget, None] = None):
        super().__init__(parent=parent)

        # 基础设置
        self.item_height = 870
        self.setFixedSize(sum(SaleInfo.sale_title_width) + 1, self.item_height)

        # 主布局
        self.main_v_layout = QVBoxLayout()
        self.main_v_layout.setContentsMargins(0, 0, 0, 0)
        self.main_v_layout.setSpacing(0)
        self.setLayout(self.main_v_layout)

        # 添加表头
        self.header = QQ9HeaderWidget()
        self.main_v_layout.addWidget(self.header)

        # 添加表格
        self.table = QQ9Table()
        self.main_v_layout.addWidget(self.table)

        # 添加合计金额
        self.total_bill = QQ9BottomBase(title = "合计金额")
        self.total_bill.value_label.setStyleSheet(
            f"""
            font-family: "{FontFamily.wechat_sans}";
            font-size: 18px;
            color: #000000;
            background-color: #FFFFFF;
            border: none;
            border-left: 1px solid #EBEEF5;
            border-right: 1px solid #EBEEF5;
            border-bottom: 1px solid #EBEEF5; 
            """
        )

        self.main_v_layout.addWidget(self.total_bill)

        # 设置样式
        self._set_style_sheet()

    def _set_style_sheet(self):
        self.setStyleSheet(
            """
            QQ9TabelWidget {
                border: none;
                border-left: 1px solid #EBEEF5;
            }
            """
        )


class QQ9EditTabelWidget(QFrame):

    def __init__(self, parent: Union[QWidget, None] = None):
        super().__init__(parent=parent)

        # 基础设置
        self.item_height = 772
        self.setFixedSize(sum(SaleInfo.sale_title_width) + 1, self.item_height)

        # 主布局
        self.main_v_layout = QVBoxLayout()
        self.main_v_layout.setContentsMargins(0, 0, 0, 0)
        self.main_v_layout.setSpacing(0)
        self.setLayout(self.main_v_layout)

        # 添加表头
        self.header = QQ9HeaderWidget()
        self.main_v_layout.addWidget(self.header)

        # 添加表格
        self.table = QQ9Table()
        self.table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.table.setFixedHeight(self.item_height - 35)
        self.main_v_layout.addWidget(self.table)

        # 设置样式
        self._set_style_sheet()

    def _set_style_sheet(self):
        self.setStyleSheet(
            """
            QQ9EditTabelWidget {
                border: none;
                border-left: 1px solid #EBEEF5;
                border-bottom: 1px solid #EBEEF5;
            }
            """
        )


# 初始化尺寸装饰器
def init_size(method):
    def wrapper(self, *args, **kwargs):
        self.clearContents()
        self.setRowCount(self.table_row)
        self.setColumnCount(self.table_column)
        method(self, *args, **kwargs)
        for i in range(self.table_row):
            self.setRowHeight(i, self.item_height)
        for col in range(len(SaleInfo.sale_title_width)):
            self.setColumnWidth(col, SaleInfo.sale_title_width[col])
        return
    return wrapper


# 居中装饰器
def align_center(method):
    def wrapper(self, *args, **kwargs):
        method(self, *args, **kwargs)
        # 获取当前行和列
        for _row in range(self.table_row):
            for _col in range(self.table_column):
                item = self.item(_row, _col)
                if item:
                    item.setTextAlignment(Qt.AlignCenter)
        return None
    return wrapper


# 全部只读装饰器
def all_read_only(method):
    def wrapper(self, *args, **kwargs):
        method(self, *args, **kwargs)
        #只读模式，禁止选中
        self.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.setSelectionMode(QAbstractItemView.NoSelection)
        # 取消焦点（虚线边框）
        self.setFocusPolicy(Qt.NoFocus)
        return None
    return wrapper


#指定列只读装饰器
def col_read_only(*o_args):
    def wrapper(method):
        def inner(self, *i_args, **kwargs):
            method(self, *i_args, **kwargs)
            for row in range(self.table_row):
                for col in range(self.table_column):
                    if col in o_args:
                        item = self.item(row, col)
                        item.setFlags(item.flags() ^ Qt.ItemIsEditable)
            return None
        return inner
    return wrapper


# 风格装饰器
def double_color_style(method):
    def wrapper(self, *args, **kwargs):
        method(self, *args, **kwargs)
        for i in range(self.table_row):
            # 设置行高
            self.setRowHeight(i, self.item_height)
            if i % 2 == 0:  # 偶数行
                for j in range(self.columnCount()):
                    if self.item(i, j) is not None:  # 确保单元格存在
                        self.item(i, j).setBackground(QColor(250, 251, 253))
                        self.item(i, j).setTextAlignment(Qt.AlignCenter)
            else:  # 奇数行
                for j in range(self.columnCount()):
                    if self.item(i, j) is not None:  # 确保单元格存在
                        self.item(i, j).setBackground(QColor(255, 255, 255))
                        self.item(i, j).setTextAlignment(Qt.AlignCenter)
        return None
    return wrapper


# 样式代理
class _QQ9TableItemDelegate(QStyledItemDelegate):

    def createEditor(self, parent: QWidget, option: QStyleOptionViewItem, index: QModelIndex) -> QWidget:
        if self.parent().current_select_col in (0, 2, 3, 4, 5, 6):
            line_edit = QQ9NoSizeNumberLineEdit(parent)
        else:
            line_edit = QQ9NoSizeLineEdit(parent)
        line_edit.setText(index.data())  # 使用 index.data() 来获取单元格数据
        return line_edit

    def updateEditorGeometry(self, editor: QWidget, option: QStyleOptionViewItem, index: QModelIndex) -> None:
        rect = option.rect
        editor.setGeometry(rect.x(), rect.y(), rect.width(), rect.height())


class QQ9Table(QTableWidget):

    def __init__(self, parent: Union[QWidget, None] = None):
        super().__init__(parent=parent)

        # 基础属性
        self.item_height = 32
        self.table_row = 25
        self.table_column = 8
        self.setFixedSize(sum(SaleInfo.sale_title_width), self.item_height * self.table_row)
        self.current_select_row, self.current_select_col = 0, 0

        # 隐藏标题栏
        self.verticalHeader().setVisible(False)
        self.horizontalHeader().setVisible(False)

        # 背景透明无边框
        self.viewport().setStyleSheet("""background-color: transparent;""")
        self.viewport().setFixedSize(sum(SaleInfo.sale_title_width), self.item_height * self.table_row)
        self.setFrameShape(QFrame.NoFrame)

        # 隐藏滑轮
        self.scrollDelegate = SmoothScrollDelegate(self)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # 设置代理
        self.delegate = _QQ9TableItemDelegate(self)
        self.setItemDelegate(self.delegate)

        # 绑定信号
        self.itemClicked.connect(self._set_current_cell)
        self.itemChanged.connect(self.auto_calculate)

        # 设置样式
        self._set_style_sheet()

    def _set_style_sheet(self):
        self.setStyleSheet(
            """
            QTableWidget {
                font-family: "微软雅黑";
                font-size: 14px;
                color: #808389;
                font-weight: bold;
                gridline-color: #EBEEF5;
                outline: none;
            }
            QTableWidget::item:selected {
                background-color: #EAEBED; /* 选中单元格的背景颜色 */
                color: #808389; /* 选中单元格的文字颜色 */
                border: none;
                padding: 0; /* 移除内部空白区 */
            }
            QTableWidget::item {
                padding: 0; /* 移除单元格内部空白区 */
            }
            QHeaderView::section {
                border: 1px solid black; /* 表头的边框 */
            }
            """.replace("#808389", TABLE_CONTENT_FONT_COLOR)
        )

    # 创建可编辑空表格
    @init_size
    @align_center
    @double_color_style
    @col_read_only(0, 4, 6)
    def create_edit_empty_table(self):
        for row in range(self.table_row):
            # 序号
            self.set_no(row)
            # 空内容
            for column in range(self.table_column):
                item = QTableWidgetItem("")
                self.setItem(row, column + 1, item)

    # 创建可编辑表
    @init_size
    @align_center
    @double_color_style
    @col_read_only(0, 4, 6)
    def create_edit_table_with_content(self, data: List[List[str]]):
        for row in range(self.table_row):
            # 序号
            self.set_no(row)
            for column in range(self.table_column - 1):
                if row > len(data) - 1:
                    item = QTableWidgetItem("")
                else:
                    item = QTableWidgetItem(data[row][column])
                self.setItem(row, column + 1, item)

    # 创建只读表
    @init_size
    @align_center
    @double_color_style
    @all_read_only
    def create_read_only_table_with_content(self, data: List[List[str]]):
        for row in range(self.table_row):
            # 序号
            self.set_no(row)
            for column in range(self.table_column - 1):
                if row > len(data) - 1:
                    item = QTableWidgetItem("")
                else:
                    if column in (3, 5) and data[row][column] == "0":
                        item = QTableWidgetItem("")
                    else:
                        item = QTableWidgetItem(data[row][column])
                self.setItem(row, column + 1, item)

    def _set_current_cell(self, cell: QTableWidgetItem):
        self.current_select_row, self.current_select_col = cell.row(), cell.column()

    def get_values(self) -> List[List[str]]:
        # 获取除了第一列的所有内容
        datas = []
        for row in range(self.rowCount()):
            row_contents = []
            for column in range(1, self.columnCount()):  # 从第2列开始遍历
                item = self.item(row, column)
                if item is not None:
                    row_contents.append(item.text())
                else:
                    row_contents.append("")  # 如果单元格为空，添加空字符串
            datas.append(row_contents)
        return datas

    def auto_calculate(self, item: QTableWidgetItem):
        # 获取触发的行
        row, col = item.row(), item.column()
        if col in (1, 2, 3, 5):
            try:
                # 件数(当为空时，按照0计算)
                num = int(self.item(row, 2).text()) if self.item(row, 2).text() != "" else 0
                # 每件卷数(当为空时，按照0计算)
                volumes = int(self.item(row, 3).text()) if self.item(row, 3).text() != "" else 0
                # 每卷单价(当为空时，按照0计算)
                unit_price = float(self.item(row, 5).text()) if self.item(row, 5).text() != "" else 0
                # 计算总卷数
                all_volumes = num * volumes
                # 当前总价
                all_price = int(all_volumes * unit_price)
                ## 上述数据都已经不为空
                # 检测品名及规格是否存在
                # 不存在时
                if self.item(row, 1).text().replace(" ", "") == "":
                    for _col in range(1, self.columnCount()):
                        self.item(row, _col).setText("")
                # 如果存在时
                else:
                    if self.item(row, 6).text() in ("0", ""):
                        for col_red in range(1, self.columnCount()):
                            self.item(row, col_red).setTextColor(QColor(255, 0, 0))
                            font = item.font()  # 获取当前字体
                            self.item(row, col_red).setFont(font)

                if self.item(row, 2).text() != "" and (self.item(row, 3).text() != ""):
                    self.item(row, 4).setText(str(all_volumes))
                if self.item(row, 4).text() != "" and (self.item(row, 5).text()  != ""):
                    self.item(row, 6).setText(str(all_price))
                    # 当总价低于1000时触发计算错误预警
                    if 0< int(all_price) <= 1000:
                        for col_blue in range(1, self.columnCount()):
                            self.item(row, col_blue).setTextColor(QColor(24,144,255))
                            font = item.font()  # 获取当前字体
                            self.item(row, col_blue).setFont(font)

                    elif int(all_price) == 0:
                        for col_red in range(1, self.columnCount()):
                            self.item(row, col_red).setTextColor(QColor(255, 0, 0))
                            font = item.font()  # 获取当前字体
                            self.item(row, col_red).setFont(font)
                    # 符合条件时复位
                    else:
                        for col_black in range(1, self.columnCount()) :
                            self.item(row, col_black).setTextColor(QColor("#909399"))
                            font = item.font()  # 获取当前字体
                            self.item(row, col_black).setFont(font)
            except Exception as e:
                pass

    def set_no(self, row:int):
        item = QTableWidgetItem(str(row + 1))
        self.setItem(row, 0, item)
        item.setTextColor(QColor(144,147,153))
        font = item.font()  # 获取当前字体
        item.setFont(font)

class _LabelBase(QLabel):

    def __init__(self, parent: Union[QWidget, None] = None, title: str = "", width: int = 50, height: int = 30, no_top_border: bool = False):
        super().__init__(parent=parent)

        # 基础设置
        self.setFixedSize(width, height)
        self.setAlignment(Qt.AlignCenter)
        self.setText(title)
        self.no_top_border = no_top_border

        # 设置样式
        self._set_style_sheet()

    def _set_style_sheet(self):
        pass


class _LHeaderLabel(_LabelBase):

    def _set_style_sheet(self):

        if not self.no_top_border:
            self.setStyleSheet(
                """
                QLabel {
                    background-color: #FFFFFF;
                    color: #909399;
                    border: none;
                    border-right: 1px solid #EBEEF5;
                    border-top: 1px solid #EBEEF5;
                    border-bottom: 1px solid #EBEEF5;
                    font-size: 14px;
                    font-weight: 400;
                    font-family: Microsoft YaHei;
                    font-weight: bold;
                }
                """
            )
        else:
            self.setStyleSheet(
                """
                QLabel {
                    background-color: #FFFFFF;
                    color: #909399;
                    border: none;
                    border-right: 1px solid #EBEEF5;
                    border-bottom: 1px solid #EBEEF5;
                    font-size: 14px;
                    font-weight: 400;
                    font-family: Microsoft YaHei;
                    font-weight: bold;
                }
                """
            )

class _RHeaderLabel(_LabelBase):

    def _set_style_sheet(self):

        if not self.no_top_border:
            self.setStyleSheet(
                """
                QLabel {
                    background-color: #FFFFFF;
                    color: #000000;
                    border: none;
                    border-left: 1px solid #EBEEF5;
                    border-right: 1px solid #EBEEF5;
                    border-top: 1px solid #EBEEF5;
                    border-bottom: 1px solid #EBEEF5;                
                    font-size: 14px;
                    font-weight: 400;
                    font-family: Microsoft YaHei;
                    font-weight: bold;
                }
                """
            )
        else:
            self.setStyleSheet(
                """
                QLabel {
                    background-color: #FFFFFF;
                    color: #000000;
                    border: none;
                    border-left: 1px solid #EBEEF5;
                    border-right: 1px solid #EBEEF5;
                    border-bottom: 1px solid #EBEEF5;                
                    font-size: 14px;
                    font-weight: 400;
                    font-family: Microsoft YaHei;
                    font-weight: bold;
                }
                """
            )


class QQ9HeaderWidget(QWidget):

    def __init__(self, parent: Union[QWidget, None] = None):
        super().__init__(parent=parent)

        # 基础属性
        self.item_height = 35
        self.setContentsMargins(0, 0, 0, 0)
        self.setFixedSize(sum(SaleInfo.sale_title_width), self.item_height)

        # 主布局
        self.main_h_layout = QHBoxLayout()
        self.main_h_layout.setContentsMargins(0, 0, 0, 0)
        self.main_h_layout.setSpacing(0)
        self.setLayout(self.main_h_layout)

        # 标题
        self.title_0 = _LHeaderLabel(title=SaleInfo.sale_title[0], width=SaleInfo.sale_title_width[0], height=self.item_height)
        self.title_1 = _LHeaderLabel(title=SaleInfo.sale_title[1], width=SaleInfo.sale_title_width[1], height=self.item_height)
        self.title_2 = _LHeaderLabel(title=SaleInfo.sale_title[2], width=SaleInfo.sale_title_width[2], height=self.item_height)
        self.title_3 = _LHeaderLabel(title=SaleInfo.sale_title[3], width=SaleInfo.sale_title_width[3], height=self.item_height)
        self.title_4 = _LHeaderLabel(title=SaleInfo.sale_title[4], width=SaleInfo.sale_title_width[4], height=self.item_height)
        self.title_5 = _LHeaderLabel(title=SaleInfo.sale_title[5], width=SaleInfo.sale_title_width[5], height=self.item_height)
        self.title_6 = _LHeaderLabel(title=SaleInfo.sale_title[6], width=SaleInfo.sale_title_width[6], height=self.item_height)
        self.title_7 = _LHeaderLabel(title=SaleInfo.sale_title[7], width=SaleInfo.sale_title_width[7], height=self.item_height)

        # 加入布局
        self.main_h_layout.addWidget(self.title_0)
        self.main_h_layout.addWidget(self.title_1)
        self.main_h_layout.addWidget(self.title_2)
        self.main_h_layout.addWidget(self.title_3)
        self.main_h_layout.addWidget(self.title_4)
        self.main_h_layout.addWidget(self.title_5)
        self.main_h_layout.addWidget(self.title_6)
        self.main_h_layout.addWidget(self.title_7)


class QQ9BottomBase(QWidget):

    def __init__(self, parent: Union[QWidget, None] = None, title = ""):
        super().__init__(parent=parent)

        # 基础属性
        self.item_height = 35
        self.setFixedSize(sum(SaleInfo.sale_title_width), self.item_height)

        # 主布局
        self.main_h_layout = QHBoxLayout()
        self.main_h_layout.setContentsMargins(0, 0, 0, 0)
        self.main_h_layout.setSpacing(0)
        self.setLayout(self.main_h_layout)

        # 标题
        self.title_label = _LHeaderLabel(title=title, width=sum(SaleInfo.sale_title_width[0:2]), height=self.item_height, no_top_border=True)

        # 值
        self.value_label = _LHeaderLabel(title="", width=sum(SaleInfo.sale_title_width[2:]), height=self.item_height, no_top_border=True)

        # 加入布局
        self.main_h_layout.addWidget(self.title_label)
        self.main_h_layout.addWidget(self.value_label)

    def set_value(self, value: str):
        self.value_label.setText("￥" + value)